#include <vector>
#include <unordered_set>
+#ifndef T_TLSA
+#define T_TLSA 52 /* TLSA certificate association */
+#endif
+
#ifndef T_CAA
# define T_CAA 257 /* Certification Authority Authorization */
#endif
return Array::New(env->isolate(), ttls.out(), naddrttls);
}
+int GetAnswerCountForTTLBuffer(const unsigned char* buf, int len) {
+ static constexpr int kDNSAnswerCountOffset = 6;
+ static constexpr int kAresDefaultTTLBufferLength = 256;
+ if (len <= kDNSAnswerCountOffset + 1) {
+ return kAresDefaultTTLBufferLength;
+ }
+
+ const int answer_count = (static_cast<int>(buf[kDNSAnswerCountOffset]) << 8) |
+ static_cast<int>(buf[kDNSAnswerCountOffset + 1]);
+ return answer_count == 0 ? 1 : answer_count;
+}
+
+template <typename T>
+std::vector<T> MakeAddrTTLBuffer(const unsigned char* buf, int len) {
+ return std::vector<T>(GetAnswerCountForTTLBuffer(buf, len));
+}
+
int ParseGeneralReply(
Environment* env,
const unsigned char* buf,
int type, status, old_count;
/* Parse A records or CNAME records */
- ares_addrttl addrttls[256];
- int naddrttls = arraysize(addrttls);
+ std::vector<ares_addrttl> addrttls =
+ MakeAddrTTLBuffer<ares_addrttl>(buf, len);
+ int naddrttls = static_cast<int>(addrttls.size());
type = ns_t_cname_or_a;
status = ParseGeneralReply(env,
len,
&type,
ret,
- addrttls,
+ addrttls.data(),
&naddrttls);
uint32_t a_count = ret->Length();
if (status != ARES_SUCCESS && status != ARES_ENODATA)
}
/* Parse AAAA records */
- ares_addr6ttl addr6ttls[256];
- int naddr6ttls = arraysize(addr6ttls);
+ std::vector<ares_addr6ttl> addr6ttls =
+ MakeAddrTTLBuffer<ares_addr6ttl>(buf, len);
+ int naddr6ttls = static_cast<int>(addr6ttls.size());
type = ns_t_aaaa;
status = ParseGeneralReply(env,
len,
&type,
ret,
- addr6ttls,
+ addr6ttls.data(),
&naddr6ttls);
uint32_t aaaa_count = ret->Length() - a_count;
if (status != ARES_SUCCESS && status != ARES_ENODATA)
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
- ares_addrttl addrttls[256];
- int naddrttls = arraysize(addrttls), status;
+ std::vector<ares_addrttl> addrttls =
+ MakeAddrTTLBuffer<ares_addrttl>(buf, len);
+ int naddrttls = static_cast<int>(addrttls.size()), status;
Local<Array> ret = Array::New(env->isolate());
int type = ns_t_a;
len,
&type,
ret,
- addrttls,
+ addrttls.data(),
&naddrttls);
if (status != ARES_SUCCESS)
return status;
- Local<Array> ttls = AddrTTLToArray<ares_addrttl>(env, addrttls, naddrttls);
+ Local<Array> ttls = AddrTTLToArray<ares_addrttl>(env, addrttls.data(), naddrttls);
wrap->CallOnComplete(ret, ttls);
return ARES_SUCCESS;
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
- ares_addr6ttl addrttls[256];
- int naddrttls = arraysize(addrttls), status;
+ std::vector<ares_addr6ttl> addrttls =
+ MakeAddrTTLBuffer<ares_addr6ttl>(buf, len);
+ int naddrttls = static_cast<int>(addrttls.size()), status;
Local<Array> ret = Array::New(env->isolate());
int type = ns_t_aaaa;
len,
&type,
ret,
- addrttls,
+ addrttls.data(),
&naddrttls);
if (status != ARES_SUCCESS)
return status;
- Local<Array> ttls = AddrTTLToArray<ares_addr6ttl>(env, addrttls, naddrttls);
+ Local<Array> ttls = AddrTTLToArray<ares_addr6ttl>(env, addrttls.data(), naddrttls);
wrap->CallOnComplete(ret, ttls);
return ARES_SUCCESS;